package com.jichaoyun.service.util;

import com.alibaba.fastjson.JSON;
import com.jichaoyun.common.enums.MyExceptiontType;
import com.jichaoyun.common.ex.MyException;

import com.jichaoyun.model.vo.UserVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class JwtUtil {

  /**
   * 自定义秘钥
   * */
  private static final String sign = "jichaoyun" ;

  /**
   * jwtToken的默认有效时间 单位分钟
   * */
  private static final int expireTime = 30 ;

  /**
   * 生成jwt token
   * @param map  要存放负载信息
   * */
  public static String createJwtToken(Map<String,Object> map){
      return  Jwts.builder()
          .setClaims(map) //放入payLoad部分的信息
          .signWith(SignatureAlgorithm.HS512,sign)
          .compact();

  }


  /**
   * 从令牌中获取数据,就是payLoad部分存放的数据。如果jwt被改，该函数会直接抛出异常
   * @param token  令牌
   * */
  public static Claims parseToken(String token){
    return Jwts.parser()
        .setSigningKey(sign)
        .parseClaimsJws(token)
        .getBody() ;
  }

  /**
   * 验证用户信息
   * @param token  jwtToken
   * */
  public static UserVo verifyJwtToken(String token){
    try{
      Claims claims = parseToken(replaceTokenPrefix(token));
      String id = String.valueOf(claims.get("id"));
      //从redis中获取用户信息
      RedisUtil redisUtil = new RedisUtil();
      UserVo uservo = JSON.parseObject(JSON.toJSONString(redisUtil.get(id)),UserVo.class);
      //判断token时间是否过期
      if(uservo==null){
        throw new MyException(MyExceptiontType.TOKENEXPIRED,null);
      }
//      if(System.currentTimeMillis()>uservo.getExpireTimeVo()){
//        //删除redis缓存
//        redisUtil.del(uservo.getId().toString());
//        throw new MyException(MyExceptiontType.TOKENEXPIRED,null);
//      }
      return uservo;
    }catch (Exception e){
      e.printStackTrace();
      throw e;
    }
  }


  /**
   * 刷新令牌时间，刷新redis缓存时间
   * @param  user 用户信息
   * */
  public static void refreshToken(UserVo user){
    //重新设置User对象的过期时间，再刷新缓存
    user.setExpireTimeVo(System.currentTimeMillis()+1000L * 60 * expireTime);
    RedisUtil redisUtil = new RedisUtil();
    redisUtil.set(user.getId().toString(),user,expireTime);
  }

  /**
   * 删除 token 的前缀
   * 前端的安全规则会在token前自动生成 Bearer 字符串前缀,共7个字符,需要删掉
   * */
  public static String replaceTokenPrefix(String token){
    return  token.substring(7);
  }

}
